home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.3d26 source
/
tn3270
/
vmxfer.c
< prev
next >
Wrap
Text File
|
1991-03-31
|
36KB
|
1,561 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.3d21, January 17, 1991
* Copyright (c) 1988, 1989, 1990, 1991 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#define __SEG__ vmxfer
#include "maclib.h"
#include <fcntl.h>
#include "termdef.h"
#define eofErr -39
#define IAC 255 /* Telnet: interpret as command: */
vmprt prtinfo = { /* defaults if VMPR 128 resource is not present */
4, /* fontnum */
10, /* pointsize */
12, /* leading */
132, /* linewidth */
4, /* tabsize */
57, /* pagelength */
59, /* pagelencc */
14, /* top */
2, /* headmarg */
12, /* left */
0, /* leftcc */
74, /* titlewidth */
0, 0, 0, 0}; /* unused fields */
char * currvname();
DateTimeRec wdate;
char statbuf[80];
char ropen, wopen; /* flags indicating file open for rd/wr */
unsigned char * rbuf; /* received data */
unsigned char * sbuf; /* data sent as reply */
short rlen; /* size of rbuf */
short slen; /* size of sbuf */
char vmxbgn; /* xfer mode active flag */
char vmxsub; /* xfer subset mode active flag */
char kabort; /* "keyboard" abort flag */
char binxf; /* binary mode file transfer */
char mbinxf; /* MacBinary file transfer */
char prtxf; /* downloading print file */
char prtcc; /* print file has carriage control */
char prpgopen; /* print page open */
char prdocopen; /* print document open */
char cmpstate; /* state for compression */
char prevchar; /* previous character for compression */
char crcok; /* true if crc has been appended */
char xlflag; /* true if XL command has been recieved */
short xfspeed; /* file transfer character rate */
short rfd, wfd; /* read & write file descriptors */
short wfd_r; /* MacBinary resource fork descriptor */
short vnum; /* volume descriptor for RMAC/WMAC */
char macFName[258]; /* complete Mac file name */
char macVName[29]; /* Mac volume name */
/* both have length byte followed by
C string */
unsigned int cursiz; /* number of sectors transferred */
unsigned int filsiz; /* total number of sectors */
char statname[14]; /* "uploading" or "downloading" */
char prtbuf2[120]; /* message buffers */
char prtbuf3[120];
char prtbuf4[120];
struct mbhdr { /* MacBinary header */
unsigned char ver; /* version byte */
unsigned char fnlen; /* length of filename */
unsigned char fn[63]; /* filename */
unsigned char ftyp[4]; /* file type */
unsigned char fcreat[4]; /* file creator */
unsigned char flags; /* finder flags */
unsigned char flags2; /* second flag byte */
unsigned char vpos[2]; /* vertical position */
unsigned char hpos[2]; /* horizontal position */
unsigned char id[2]; /* window or folder ID */
unsigned char pflag; /* "protected" flag */
unsigned char zero2; /* zero */
unsigned char dataln[4]; /* data fork length */
unsigned char rscln[4]; /* resource fork length */
unsigned char crdate[4]; /* creation date */
unsigned char mddate[4]; /* last modified date */
unsigned char zero3[29]; /* zero fill */
} mh;
long mbdbmax; /* MacBin data size in blocks */
long mbrbmax; /* MacBin resource size in blocks */
long mbdsize; /* MacBin data fork length */
long mbrsize; /* MacBin resource fork size */
long mbdextra; /* MacBin data fork padding */
long mbrextra; /* MacBin resource fork padding */
extern char int_active; /* interrupt routine running */
extern char serflg; /* serial connection */
extern char tcpflg; /* 0 = PC Net; 1 = TCP/IP */
extern char xdlg;
extern DialogPtr xdlgptr;
extern struct GrafPort *myWindow;
extern struct Point sfppoint, sfgpoint;
extern THPrint hPrint; /* print record handle */
extern char prtinit; /* flag for printing intialization */
extern char csnlname[];
extern unsigned char **nl_handle; /* handle to current language mapping */
extern unsigned char nltab[]; /* national language translation table */
extern settings_list cs;
static TPPrPort prtport;
long atol();
long chartolong();
OSErr prtwrite();
vmxfer()
{
/* In xfer mode, the Mac program acts as a slave to VM/370,
executing each command from VM (a command may include data
to be processed) and returning a return code or data block. */
register short c; /* variable for i/o calls */
register short i; /* loop counter */
short rmax; /* count for uncompress loop */
char rchk[5]; /* received checksum string */
char cchk[5]; /* computed checksum string */
char cmdok; /* if true, command is ok */
/* process a command from VM */
slen = 0;
if ((rlen==2) && (rbuf[0]==XFBGN) && (rbuf[1]==XFBGN)) {
xfrst();
vmxbgn = 1; /* set xfer mode */
xfdlg(0);
return;
}
if (!vmxbgn) {
sbuf[slen++] = ' ';
return;
}
if ((rlen==1) && (rbuf[0]==DC4)) { /* subset code */
if (vmxsub) {
if (xdlg) SelectWindow(xdlgptr);
}
else SelectWindow(myWindow);
vmxsub ^= 1;
if (serflg || tcpflg) newstat();
else if (!int_active) newstat();
return;
}
/* process compressed data */
if ((rlen > 6) && (rbuf[0] == 0x18)) {
movmem(rbuf+1, sbuf, rlen-1); /* copy data without prefix */
cmpstate = 0;
rmax = rlen-6; /* length without prefix or CRC */
rlen = 0;
for (i=0; i < rmax; i++) datachr(&rlen, sbuf[i]);
while(i < rmax+5) rbuf[rlen++] = sbuf[i++]; /* append CRC */
}
/* verify data read is valid; if not, set cmdok FALSE */
if ((rlen > 6) & (rlen < 2320)) {
rbuf[rlen] = '\0'; /* delimit received checksum */
strcpy(rchk,rbuf+rlen-4); /* copy checksum */
rbuf[rlen-5] = '\0'; /* delimit data */
rlen -= 5; /* rlen = data length */
chkdata(rbuf,rlen,cchk); /* calculate data checksum */
cmdok = (strcmp(rchk,cchk) == 0); /* compare checksums */
}
else cmdok = 0;
/* If command is ok, return the result of attempting to execute
it. If the command is in error, just transmit a blank. */
if (cmdok) {
crcok = 0; /* no CRC yet */
excmmd(); /* execute command */
if (crcok == 0) { /* append CRC if needed */
if (slen == 0) slen = strlen(sbuf); /* get data length */
chkdata(sbuf,slen,cchk); /* get checksum */
sbuf[slen] = CD; /* delimit checksum */
movmem(cchk, sbuf+slen+1, 4); /* append checksum */
slen += 5; /* update length */
}
}
else sbuf[slen++] = ' ';
}
chkdata(buf,len,chk)
register char *buf, *chk;
register short len;
{
register char i;
unsigned short crcf();
/* calculate four-byte ASCII checksum for buf in chk */
sprintf(chk,"%4x",crcf(buf,len,0));
for (i = 0; i < 4; i++) /* convert blanks to zeros */
if (chk[i] == ' ') chk[i] = '0';
else chk[i] = toupper(chk[i]);
}
excmmd()
{
register unsigned short i;
i = (rbuf[0] << 8) + rbuf[1];
switch(i) {
case 0x4f49: /* 'OI' */
rdopen();
break;
case 0x4249: /* 'BI' */
rdopen();
break;
case 0x5242: /* 'RB' */
rdblock();
break;
case 0x4349: /* 'CI' */
rdclose();
break;
case 0x4f4f: /* 'OO' ASCII Output (old WMAC) */
case 0x414f: /* 'AO' Alternate Output (new WMAC) */
case 0x424f: /* 'BO' Binary Output (new WMAC) */
case 0x4d4f: /* 'MO' MacBinary Output (new WMAC) */
case 0x4d48: /* 'MH' MacBinary Header (new WMAC) */
wropen();
break;
case 0x5742: /* 'WB' */
wrblock();
break;
case 0x434f: /* 'CO' */
wrclose();
break;
case 0x4558: /* 'EX' */
exitcmd();
break;
case 0x5652: /* 'VR' */
verscmd();
break;
case 0x5454: /* 'TT' */
trtime();
break;
case 0x584c: /* 'XL' */
xlcmd();
break;
default:
setrc(28);
break;
}
}
setrc(code)
register short code;
{
register char i;
sprintf(sbuf,"RC%4d",code);
for (i = 2; i < 6; i++)
if (sbuf[i] == ' ') sbuf[i] = '0';
}
rdopen()
{
short rdlast;
short rdvnum;
register short rc;
register char nomenu, rdcancel;
long fsize;
struct DateTimeRec fdate;
rdcancel = 0;
nomenu = 0; /* handle menu option */
rdlast = strlen(rbuf+2) + 1;
if (rbuf[rdlast] == '*') {
rbuf[rdlast] = 0;
nomenu = 1;
}
binxf = (rbuf[0] == 'B');
rc = -1; /* simulate open error for menu */
ropen = 0;
if (nomenu) {
strcpy(macVName+1,currvname()); /* get default volume */
macVName[0] = strlen(macVName+1);
strcpy(macFName+1,rbuf+2); /* get file id */
macFName[0] = strlen(macFName+1);
rc = fsrdopen(macFName+1, vnum, &rfd);
}
if (rc != 0) { /* get id from user */
getrd(macFName);
if (macFName[0] == 0) rdcancel = 1;
if (!rdcancel)
rc = fsrdopen(macFName+1, vnum, &rfd);
}
if (rc != 0) {
if (!rdcancel) stoperr(300);
setrc(1);
return;
}
if (rc == 0) ropen = 1;
strcpy(statname,"Uploading");
getinfo(&fsize,&fdate);
filsiz = (fsize + 127) >> 7;
cursiz = 0;
strcpy(sbuf,"AT"); /* success: return file attributes */
if (binxf) sbuf[0] = 'B'; /* use BT for binary transfer */
sprintf(sbuf+2,"%04x",filsiz); /* file size */
sprintf(sbuf+6,"%04d%02d%02d%02d%02d%02d", /* date */
fdate.year,fdate.month,fdate.day,fdate.hour,
fdate.minute,fdate.second);
}
rdclose()
{
ropen = 0;
if (FSClose(rfd) != 0) setrc(1); /* close input file */
else {
FlushVol(0L, vnum);
setrc(0);
}
}
rdblock()
{
short rc, rdlen, padlen;
register short i, reccnt;
char blkstr[5], eof, trflg, padchr;
register unsigned char c, maxchar;
unsigned long recnum, r_byte;
short iaccount, dest, src;
char cchk[5]; /* computed checksum string */
if (kabort) { /* set rc 11 for subset/abort */
setrc(11);
kabort = 0;
return;
}
/* give error 3 if block number and speed not read */
if (rlen < 10) {
setrc(3);
return;
}
/* extract xfspeed and save */
movmem(rbuf+6,blkstr,4);
blkstr[4] = '\0';
xfspeed = atoi(blkstr);
/* extract block number and convert to record */
movmem(rbuf+2,blkstr,4);
blkstr[4] = '\0';
recnum = atol(blkstr); /* record = block * 18 */
recnum *= 18;
/* read 18 records (2304 bytes) or less at end of file */
strcpy(sbuf,"DB"); /* store data block prefix */
typstat();
r_byte = recnum << 7; /* byte offset = record * 128 */
rc = SetFPos(rfd, 1, r_byte); /* position for read */
if (rc == eofErr) { /* rc 1 for eof */
setrc(1);
return;
}
else if (rc != 0) {
stoperr(301);
setrc(8);
return;
}
r_byte = 2304; /* read next 2304 bytes of data */
rc = FSRead(rfd, &r_byte, sbuf+2);
if ((rc != eofErr) && (rc != 0)) { /* check for errors */
stoperr(301);
setrc(9);
return;
}
if (r_byte == 0) { /* assume eof if zero bytes read */
setrc(1);
return;
}
rdlen = r_byte;
padlen = 128 - (rdlen % 128); /* pad to a multiple of 128 */
if (binxf) padchr = 0;
else padchr = CPMEOF;
if (padlen < 128) {
rdlen += 2;
for (i=0; i < padlen; i++) sbuf[rdlen++] = padchr;
rdlen -= 2;
}
if (binxf) slen = rdlen+2;
else sbuf[rdlen+2] = '\0';
reccnt = rdlen >> 7; /* no. of 128-byte blocks */
if (reccnt > 0) cursiz = recnum + reccnt;
/* For TCP/IP binary transfer, quoting must be inserted for the IAC
character (X'FF') by replacing each IAC by two of them */
if (binxf && tcpflg) {
/* append CRC before changing data */
chkdata(sbuf,slen,cchk); /* get checksum */
sbuf[slen] = CD; /* delimit checksum */
movmem(cchk, sbuf+slen+1, 4); /* append checksum */
slen += 5; /* update length */
crcok = 1; /* tell mainline CRC done */
/* now handle IAC characters */
iaccount = 0;
for (i=2; i < slen; i++) {
if (sbuf[i] == IAC) iaccount++;
}
if (iaccount == 0) return;
dest = slen + iaccount - 1;
src = slen - 1;
slen += iaccount;
while (iaccount > 0) {
sbuf[dest--] = c = sbuf[src--];
if (c == IAC) {
sbuf[dest--] = IAC;
iaccount--;
}
}
return;
}
if (binxf) return;
/* translate invalid characters to "|" and display file
data on terminal */
eof = trflg = 0;
rdlen += 2;
/* versions of RMAC/WMAC which issue the XL command also support Macintosh
extended ASCII, and can translate characters through X'DE' */
if (xlflag) maxchar = 222;
else maxchar = 126;
for (i = 2; i < rdlen; i++) {
if (eof) {
sbuf[i] = '\0';
break;
}
c = sbuf[i];
switch (c) {
case TAB:
case LF:
case FF:
break;
case CR:
sbuf[i] = VT;
break;
case CPMEOF:
eof = 1;
break;
case DEL:
trflg = 1;
sbuf[i] = '|';
break;
default:
if ((c < 32) || (c > maxchar)) {
trflg = 1;
sbuf[i] = '|';
}
break;
}
}
if (trflg) stoperr(302);
}
typstat() /* output transfer status */
{
char tofrom[5];
short i;
unsigned percent, min, sec, ovrhead;
long lcvt, lchar, curbytes, totbytes;
curbytes = (long)cursiz << 7;
totbytes = (long)filsiz << 7;
lcvt = cursiz;
percent = (lcvt*100)/filsiz;
if (prtxf) {
sprintf(statbuf, "%s '%s'", statname, macFName+1);
}
else {
if (statname[0] == 'D') strcpy(tofrom,"to");
else strcpy(tofrom,"from");
sprintf(statbuf,"%s '%s' %s '%s'", statname, macFName+1,
tofrom, macVName+1);
}
sprintf(prtbuf2,"%ld/%ld (%d%%)", curbytes, totbytes, percent);
if (xfspeed == 0) {
sprintf(prtbuf3,"");
sprintf(prtbuf4,"??:??");
}
else {
ovrhead = (filsiz-cursiz+7)/8; /* no. of rb/wb cmmds. */
if (statname[0] == 'D') ovrhead *= 30;
else ovrhead *= 26;
lchar = filsiz - cursiz; /* get total character count */
lchar <<= 7;
lchar += ovrhead; /* plus overhead */
lcvt = xfspeed;
sec = lchar/lcvt; /* get seconds */
min = sec / 60;
sec = sec % 60;
sprintf(prtbuf3,"%d",xfspeed);
sprintf(prtbuf4,"%d:%02d",
min,sec);
}
xfdlg(1,statbuf,prtbuf2,prtbuf3,prtbuf4);
}
wropen()
{
char cvtbuff[5];
register char c;
short rdlast;
register short rc;
unsigned short i;
register unsigned long freeBytes, totBytes;
VolumeParam pb;
struct DateTimeRec fdate;
int year, month, day, hour, minute, second;
static char nomenu;
char mhcmd;
HFileParam pbf;
GrafPtr gp;
static char listingft1[] = "listing";
static char listingft2[] = "LISTING";
static long minus1 = -1;
mhcmd = (rbuf[0] == 'M') && (rbuf[1] == 'H');
if (mhcmd) {
movmem(rbuf+2, &mh, 128); /* save header */
if ((mh.fnlen == 0) || (mh.fnlen > 63)) {
stoperr(303);
setrc(64); /* check for valid fn length */
return;
}
ptoc(&mh.fnlen); /* convert filename to C format */
mbdsize = chartolong(mh.dataln); /* get lengths of forks */
mbrsize = chartolong(mh.rscln);
mbdbmax = (mbdsize+127) >> 7; /* get block counts */
mbrbmax = (mbrsize+127) >> 7;
mbdextra = (mbdbmax << 7) - mbdsize; /* get padding counts */
mbrextra = (mbrbmax << 7) - mbrsize;
}
else { /* if not MH, get info. from rbuf */
/* set nomenu or prtxf flag */
nomenu = 0;
prtxf = 0;
rdlast = strlen(rbuf+20) + 19;
if (rbuf[rdlast] == '*') {
rbuf[rdlast] = 0;
nomenu = 1;
}
else if (rbuf[rdlast] == '.') {
rbuf[rdlast] = 0;
prtxf = 1;
}
/* get file size */
movmem(rbuf+2,cvtbuff,4);
cvtbuff[4] = '\0';
sscanf(cvtbuff,"%x",&filsiz);
/* get file date and time */
sscanf(rbuf+6,"%4d%2d%2d%2d%2d%2d",
&year,&month,&day,&hour,
&minute,&second);
fdate.year = year;
fdate.month = month;
fdate.day = day;
fdate.hour = hour;
fdate.minute = minute;
fdate.second = second;
fdate.dayOfWeek = 0;
wdate = fdate;
}
if ((rbuf[0] == 'M') && (rbuf[1] == 'O')) {
/* finish MO processing */
binxf = mbinxf = 1;
prtxf = 0;
strcpy(sbuf,"MT");
return;
}
/* set binxf, mbinxf for all but "MO" */
if (rbuf[1] == 'O') {
binxf = (rbuf[0] == 'B');
mbinxf = 0;
}
/* get file id to use */
if (!prtxf) {
if (nomenu) {
strcpy(macVName+1, currvname());
macVName[0] = strlen(macVName+1);
if (mhcmd) strcpy(macFName+1, &mh.fnlen);
else strcpy(macFName+1,rbuf+20);
macFName[0] = strlen(macFName+1);
/* check if file already exists */
rc = FSOpen(macFName+1, vnum, &wfd);
if (rc == 0) {
setrc(1);
FSClose(wfd);
FlushVol(0L, vnum);
return;
}
}
else if (mhcmd) getwr(&mh.fnlen, macFName);
else getwr(rbuf+20, macFName);
if (strlen(macFName) == 0) {
setrc(5);
return;
}
}
else {
strcpy(macFName+1, rbuf+20);
macFName[0] = strlen(macFName+1);
i = macFName[0] - strlen(listingft1);
if (i >= 2)
prtcc = (strcmp(listingft1, macFName+i+1) == 0) ||
(strcmp(listingft2, macFName+i+1) == 0);
else
prtcc = 0;
prtwrite(&minus1, 0L); /* prtwrite initialization */
}
/* now ready to use file id */
if (!prtxf) {
/* initialize for file calls */
setmem(&pbf, sizeof(HFileParam), 0);
/* delete any existing file */
pbf.ioNamePtr = (StringPtr)macFName;
pbf.ioVRefNum = vnum;
PBDelete(&pbf, 0);
/* create new file */
rc = PBCreate(&pbf, 0);
if (rc != 0) {
stoperr(303);
setrc(2);
return;
}
/* set finder info */
rc = PBGetFInfo(&pbf, 0);
if (rc != 0) {
stoperr(303);
setrc(2);
return;
}
/* set finder flags */
if (mbinxf) {
i = mh.flags;
i <<= 8;
pbf.ioFlFndrInfo.fdFlags &= 0x00ff;
pbf.ioFlFndrInfo.fdFlags |= i;
pbf.ioFlFndrInfo.fdFlags &= 0xf8ff;
}
else pbf.ioFlFndrInfo.fdFlags &= 0xfeff;
/* set type and creator */
if (mbinxf) {
movmem(mh.ftyp, &pbf.ioFlFndrInfo.fdType, 4);
movmem(mh.fcreat, &pbf.ioFlFndrInfo.fdCreator, 4);
}
else {
pbf.ioFlFndrInfo.fdType = 'TEXT';
pbf.ioFlFndrInfo.fdCreator = cs.text_creator;
}
rc = PBSetFInfo(&pbf, 0);
if (rc != 0) {
stoperr(303);
setrc(2);
return;
}
/* open data fork */
setmem(&pbf, sizeof(HFileParam), 0);
pbf.ioNamePtr = (StringPtr)macFName;
pbf.ioVRefNum = vnum;
pbf.filler1 = fsWrPerm; /* ioPermssn */
rc = PBOpen(&pbf, 0);
if (rc != 0) {
stoperr(303);
setrc(2);
return;
}
else wfd = pbf.ioFRefNum;
/* open resource fork if MacBinary */
if (mbinxf) {
rc = PBOpenRF(&pbf, 0);
if (rc != 0) {
stoperr(303);
setrc(2);
return;
}
else wfd_r = pbf.ioFRefNum;
}
}
else {
if (hPrint == 0) {
stoperr(305);
setrc(2);
return;
}
arrowcursor();
if (prtinit == 0) {
PrOpen();
PrintDefault(hPrint);
prtinit = 1;
}
if (!PrJobDialog(hPrint)) {
setrc(5);
return;
}
GetPort(&gp);
setdoctitle(macFName+1);
prtport = PrOpenDoc(hPrint, 0L, 0L);
SetPort(gp);
prdocopen = 1; /* document now open */
}
wopen = 1;
if (binxf && (!mbinxf)) strcpy(sbuf,"BT");
else setrc(0);
if (prtxf) strcpy(statname, "Printing");
else strcpy(statname,"Downloading");
if (!prtxf) {
pb.ioCompletion = 0;
pb.ioNamePtr = 0;
pb.ioVRefNum = vnum;
pb.ioVolIndex = 0;
PBGetVInfo(&pb, 0);
freeBytes = pb.ioVFrBlk * pb.ioVAlBlkSiz;
totBytes = (long) filsiz << 7;
if (freeBytes < totBytes) {
totBytes = (totBytes - freeBytes + 1023) >> 10;
dFullAlt((short) totBytes);
FSClose(wfd);
if (mbinxf) FSClose(wfd_r);
FSDelete(macFName+1, vnum);
setrc(99);
return;
}
}
cursiz = 0;
typstat();
}
wrclose()
{
short rc1, rc2;
wopen = 0;
if (!prtxf) {
rc1 = FSClose(wfd);
if (mbinxf) rc2 = FSClose(wfd_r);
else rc2 = 0;
if ((rc1 != 0) || (rc2 != 0)) {
FlushVol(0L, vnum);
stoperr(304);
setrc(1);
}
else {
rc1 = settime(&wdate, &mh);
setrc(rc1);
FlushVol(0L, vnum);
}
}
else setrc(xfprtclose());
}
int xfprtclose()
{
int rc;
TPrStatus prStatus;
static long minus3 = -3;
GrafPtr gp;
prtwrite(&minus3, 0L); /* termination call */
GetPort(&gp);
if (prpgopen) {
SetPort(prtport);
PrClosePage(prtport);
}
if (prdocopen) {
SetPort(prtport);
PrCloseDoc(prtport);
if (((*hPrint)->prJob.bJDocLoop == bSpoolLoop) && (PrError() == noErr))
PrPicFile(hPrint, 0L, 0L, 0L, &prStatus);
if (PrError() != noErr) {
stoperr(305);
rc = 1;
}
else rc = 0;
}
else rc = 0;
SetPort(gp);
prtxf = prpgopen = prdocopen = 0;
return(rc);
}
wrblock()
{
register short i, reccnt;
register short padlen;
short typlen, bufwrite();
char blkstr[5], c;
unsigned long recnum, w_byte;
OSErr rc;
if (kabort) { /* set rc 11 for subset/abort */
setrc(11);
kabort = 0;
return;
}
/* rbuf should contain: WBnnnnssssxxxx..., where "nnnn" is
the block number, "ssss" is the transfer speed in cps,
and "xxxx..." is the data to write. */
/* give error 3 if block number and speed not read */
if (rlen < 10) {
setrc(3);
return;
}
/* translate SO, VT to CR, LF */
typlen = rlen - 10;
if (!binxf) for (i=0; i < typlen; i++) {
c = rbuf[i+10];
switch (c) {
case CPMEOF: /* ignore EOF char */
break;
case SO: /* SO is translated CR */
rbuf[i+10] = CR;
break;
case VT: /* VT is translated LF */
rbuf[i+10] = LF;
break;
case FF:
break;
default:
break;
}
}
/* extract xfspeed and save */
movmem(rbuf+6,blkstr,4);
blkstr[4] = '\0';
xfspeed = atoi(blkstr);
/* extract block number and convert to record */
movmem(rbuf+2,blkstr,4);
blkstr[4] = '\0';
recnum = atol(blkstr); /* record = block * 18 */
recnum *= 18;
/* assume eof if < 2304 bytes to write; pad with EOF char
to make a multiple of 128 bytes */
padlen = 128 - ((rlen-10) % 128);
if (binxf) {
if (padlen < 128) reccnt = (padlen+rlen-10) >> 7;
else reccnt = (rlen-10) >> 7;
}
else {
if (padlen < 128)
for (i=0; i < padlen; i++) rbuf[rlen++] = CPMEOF;
reccnt = (rlen-10) >> 7; /* divide by 128 to get block count */
}
/* return now if no blocks to write (should only happen at eof) */
if (reccnt == 0) {
setrc(0);
return;
}
/* for a text file, delete trailing EOF characters */
if (!binxf) {
rlen--; /* convert length to rbuf offset */
while (rlen >= 10) {
if (rbuf[rlen] != CPMEOF) break;
rlen--;
}
rlen++; /* convert back to length */
if (rlen == 10) { /* return if only EOF characters */
setrc(0);
return;
}
}
/* write data to disk. give return code 4 for an error */
if ((!mbinxf) && (!prtxf)) {
w_byte = recnum << 7; /* get byte offset */
rc = SetFPos(wfd, 1, w_byte);
if (rc != 0) {
stoperr(304);
setrc(4);
return;
}
}
w_byte = rlen-10;
if (mbinxf) rc = mbwrite(&w_byte, rbuf+10, recnum);
else if (prtxf) rc = prtwrite(&w_byte, rbuf+10);
else rc = FSWrite(wfd, &w_byte, rbuf+10);
if ((rc != 0) || (w_byte != rlen-10)) {
if (prtxf) stoperr(305);
else stoperr(304);
setrc(5);
return;
}
setrc(0);
cursiz = recnum + reccnt;
typstat();
}
exitcmd() /* exit command */
{
setrc(0);
xfrst();
}
verscmd() /* return version info */
{
strcpy(sbuf,"VIM0231"); /* Mac3270 version 2.31 */
/* append national language name */
strcat(sbuf, ":");
strcat(sbuf, csnlname);
}
xlcmd() /* return national language translation info. */
{
unsigned char *sptr;
register short i, x, j;
xlflag = 1;
strcpy(sbuf, "XI"); /* translation info */
sptr = sbuf+2;
if (nl_handle != 0) {
for (i=0; i < 256; i++) {
x = nltab[i];
if (x != i) {
sprintf(sptr, "%02x%02x", i, x);
for (j=0; j < 4; j++) {
sptr[j] = toupper(sptr[j]);
}
sptr += 4;
}
}
}
}
trtime() /* read and display new transfer time */
{
char blkstr[5];
/* extract xfspeed and save */
movmem(rbuf+2,blkstr,4);
blkstr[4] = '\0';
xfspeed = atoi(blkstr);
/* display new status */
typstat();
/* return normal rc */
setrc(0);
}
getrd(macname)
register char *macname;
{
Point where;
unsigned short (*fileFilter)();
register short numTypes;
SFTypeList typeList;
ProcPtr dlgHook;
SFReply reply;
VolumeParam pbrec;
register VolumeParam * _pbrec;
pascal unsigned short onlydata();
_pbrec = &pbrec;
where = sfgpoint;
dlgHook = 0;
fileFilter = onlydata;
numTypes = -1;
arrowcursor();
SFGetFile(&where,"",fileFilter,numTypes,
typeList, dlgHook, &reply);
macname[0] = macname[1] = '\0';
if (reply.good == 0) return;
macname[0] = reply.fName.length;
strcpy(macname+1, ptoc(&reply.fName));
vnum = reply.vRefNum;
pbrec.ioCompletion = 0;
pbrec.ioVRefNum = vnum;
pbrec.ioVolIndex = 0;
pbrec.ioNamePtr = (StringPtr)macVName;
PBGetVInfo(_pbrec, 0);
macVName[1+macVName[0]] = '\0';
}
pascal unsigned short onlydata(_pb)
FileParam * _pb;
{
if (_pb->ioFlLgLen == 0L) return(0x100);
else return(0);
}
getwr(suggid,macname)
register char * suggid;
register char *macname;
{
Point where;
ProcPtr dlgHook;
SFReply reply;
VolumeParam pbrec;
VolumeParam * _pbrec;
_pbrec = &pbrec;
where = sfppoint;
dlgHook = 0;
/* ctop(suggid); */
arrowcursor();
SFPutFile(&where,"Save downloaded file as:",
suggid,dlgHook,&reply);
/* ptoc(suggid); */
macname[0] = macname[1] = '\0';
if (reply.good == 0) return;
macname[0] = reply.fName.length;
strcpy(macname+1, ptoc(&reply.fName));
vnum = reply.vRefNum;
pbrec.ioCompletion = 0;
pbrec.ioVRefNum = vnum;
pbrec.ioVolIndex = 0;
pbrec.ioNamePtr = (StringPtr)macVName;
PBGetVInfo(_pbrec, 0);
macVName[1+macVName[0]] = '\0';
}
char * currvname()
{
static char rtnvol[28];
VolumeParam pb;
OSErr rc;
pb.ioCompletion = 0;
pb.ioNamePtr = (StringPtr)rtnvol;
pb.ioVRefNum = vnum;
pb.ioVolIndex = 0;
rc = PBGetVInfo(&pb, 0);
if (rc == 0) ptoc(rtnvol);
else GetVol(rtnvol, &vnum);
return(rtnvol);
}
getinfo(fsize, fdate)
register long * fsize;
struct DateTimeRec * fdate;
{
FileParam fblk;
register FileParam * _fblk;
_fblk = &fblk;
fblk.ioCompletion = 0;
fblk.ioNamePtr = (StringPtr)macFName;
fblk.ioVRefNum = vnum;
fblk.ioFVersNum = 0;
fblk.ioFDirIndex = 0;
PBGetFInfo(_fblk,0);
*fsize = fblk.ioFlLgLen;
Secs2Date(fblk.ioFlMdDat, fdate);
}
settime(fdate, mh)
register struct DateTimeRec * fdate;
struct mbhdr * mh;
{
FileParam fblk;
long crsecs, mdsecs;
OSErr rc;
setmem(&fblk, sizeof(FileParam), 0);
fblk.ioNamePtr = (StringPtr)macFName;
fblk.ioVRefNum = vnum;
rc = PBGetFInfo(&fblk,0);
if (rc != 0) return(rc+200);
Date2Secs(fdate, &fblk.ioFlMdDat);
Date2Secs(fdate, &fblk.ioFlCrDat);
if (mbinxf) {
crsecs = chartolong(mh->crdate);
mdsecs = chartolong(mh->mddate);
if ((crsecs != 0) && (mdsecs != 0)) {
fblk.ioFlMdDat = mdsecs;
fblk.ioFlCrDat = crsecs;
}
}
rc = PBSetFInfo(&fblk,0);
if (rc != 0) return(rc+300);
else return(0);
}
xfrst()
{
short rc;
if (prtxf) xfprtclose();
else {
if (ropen) if (FSClose(rfd) == 0) FlushVol(0L, vnum);
if (wopen) {
rc = FSClose(wfd);
if ((rc == 0) && mbinxf) rc = FSClose(wfd_r);
if (rc == 0) FlushVol(0L, vnum);
}
}
xfdlg(2);
xfinit();
}
xfinit()
{
vmxsub = vmxbgn = 0;
kabort = 0;
ropen = wopen = 0;
xfspeed = 0;
xdlg = 0;
prtxf = 0;
prdocopen = 0;
prpgopen = 0;
xlflag = 0;
if (myWindow != 0) {
if (serflg || tcpflg) newstat();
else if (!int_active) newstat();
}
}
datachr(rdoff, c)
short * rdoff;
unsigned char c;
{
short count, max;
switch(cmpstate) {
case 0: /* normal character */
if (c == 0x18) cmpstate = 1;
else {
rbuf[(*rdoff)++] = c;
prevchar = c;
}
break;
case 1: /* after x'18' */
if (c == 0x18) { /* literal x'18' */
rbuf[(*rdoff)++] = c;
prevchar = c;
}
else { /* compression count */
count = (c - 0x20) + 2;
max = 2320 - (*rdoff);
if (count > max) count = max;
while (count > 0) {
rbuf[(*rdoff)++] = prevchar;
count--;
}
}
cmpstate = 0;
break;
default:
break;
}
}
long chartolong(str)
char * str;
{
union {
char s[4];
long l;
} u;
movmem(str, u.s, 4);
return(u.l);
}
mbwrite(count, data, offset)
long * count;
char * data;
unsigned long offset;
{
long bcnt, tsize, wsize;
short rc;
char * newdata;
long newcount;
long mbdbcnt, mbrbcnt, mbtotal;
long pos;
/* set block counts file block offset */
mbtotal = mbdbmax + mbrbmax;
if (offset > mbtotal) return(999);
if ((offset == mbtotal) && ((*count) != 0)) return(998);
if (offset >= mbdbmax) {
mbdbcnt = 0;
mbrbcnt = mbtotal - offset;
}
else {
mbdbcnt = mbdbmax - offset;
mbrbcnt = mbrbmax;
}
bcnt = ((*count) + 127) >> 7;
if (bcnt > (mbdbcnt + mbrbcnt)) bcnt = mbdbcnt + mbrbcnt;
if (bcnt == 0) return(0);
newdata = data; /* init. data for resource fork */
newcount = (*count);
if (mbdbcnt > 0) {
if (bcnt <= mbdbcnt) { /* all blocks in data fork */
wsize = bcnt << 7;
if (bcnt == mbdbcnt) wsize -= mbdextra;
tsize = wsize;
if (wsize <= (*count)) {
pos = (mbdbmax - mbdbcnt) << 7;
rc = SetFPos(wfd, 1, pos);
if (rc == 0) rc = FSWrite(wfd, &wsize, data);
}
else rc = -999;
if ((rc == 0) && (wsize == tsize)) return(0);
else {
(*count) = 0;
return(rc);
}
}
else { /* blocks for resource fork too */
wsize = mbdbcnt << 7;
newdata = data + wsize;
newcount = (*count) - wsize;
wsize -= mbdextra;
tsize = wsize;
pos = (mbdbmax - mbdbcnt) << 7;
rc = SetFPos(wfd, 1, pos);
if (rc == 0) rc = FSWrite(wfd, &wsize, data);
if ((rc == 0) && (wsize == tsize)) bcnt -= mbdbcnt;
else {
(*count) = 0;
return(rc);
}
}
}
/* all remaining blocks for resource fork */
wsize = bcnt << 7;
if (bcnt == mbrbcnt) wsize -= mbrextra;
tsize = wsize;
if (wsize <= newcount) {
pos = (mbrbmax - mbrbcnt) << 7;
rc = SetFPos(wfd_r, 1, pos);
if (rc == 0) rc = FSWrite(wfd_r, &wsize, newdata);
}
else rc = -999;
if ((rc == 0) && (wsize == tsize)) {
mbrbcnt -= bcnt;
return(0);
}
else {
(*count) = 0;
return(rc);
}
}
OSErr prtwrite(count, addr)
long * count;
unsigned char * addr;
{
static char newline1[MAXLINEWIDTH+2]; /* extra space for cc and null */
static char newline2[MAXLINEWIDTH+2];
static short prtlen, prtlen1, prtlen2;
static char nextcc;
static long minus1 = -1;
static long minus2 = -2;
static long minus3 = -3;
unsigned short c, i, j;
if (((*count) == 0) || ((*count) < -3)) return(0);
if (((*count) == -1) || ((*count) == -2)) { /* initialization calls */
setmem(newline1, MAXLINEWIDTH+2, ' '); /* -1 for new page */
setmem(newline2, MAXLINEWIDTH+2, ' '); /* -2 for new line */
if (prtcc) prtlen = prtlen1 = prtlen2 = 0;
else prtlen = prtlen1 = prtlen2 = 1;
if ((*count) == -1) nextcc = '1';
else nextcc = ' ';
return(0);
}
if ((*count) == -3) { /* termination call */
if (prtcc) {
if (prtlen1 > 0) {
newline1[prtlen1] = 0;
prtline(newline1);
}
}
else {
if (prtlen1 > 1) {
newline1[0] = nextcc;
nextcc = '+';
newline1[prtlen1] = 0;
prtline(newline1);
}
if (prtlen2 > 1) {
newline2[0] = nextcc;
nextcc = '+';
newline2[prtlen2] = 0;
prtline(newline2);
}
}
return(0);
}
for (i = 0; i < (*count); i++) {
c = addr[i];
if (prtcc)
switch(c) {
case TAB:
if (prtlen1 < prtinfo.linewidth+1) prtlen1++;
while ((((prtlen1-1) % prtinfo.tabsize) != 0) &&
((prtlen1-1) < prtinfo.linewidth+1))
prtlen1++;
break;
case CR:
if (prtlen1 == 0) newline1[prtlen1++] = ' ';
prtwrite(&minus3, 0L);
prtwrite(&minus2, 0L);
break;
default:
if (prtlen1 < prtinfo.linewidth+1)
newline1[prtlen1++] = c;
break;
}
else
switch (c) {
case BS:
if (prtlen > 1) prtlen--;
break;
case CR:
if ((prtlen1 == 1) && (prtlen2 == 1))
newline1[prtlen1++] = ' ';
prtwrite(&minus3, 0L);
prtwrite(&minus2, 0L);
break;
case LF:
j = prtlen;
if ((prtlen1 == 1) && (prtlen2 == 1))
newline1[prtlen1++] = ' ';
prtwrite(&minus3, 0L);
prtwrite(&minus2, 0L);
prtlen = j;
break;
case FF:
prtwrite(&minus3, 0L);
prtwrite(&minus1, 0L);
prtlen1 = 2;
break;
case TAB:
if (prtlen < prtinfo.linewidth+1) prtlen++;
while ((((prtlen-1) % prtinfo.tabsize) != 0) &&
((prtlen-1) < prtinfo.linewidth+1))
prtlen++;
break;
default:
if (prtlen < prtinfo.linewidth) {
if (newline1[prtlen] == ' ') {
newline1[prtlen++] = c;
if (prtlen > prtlen1) prtlen1 = prtlen;
}
else if (newline2[prtlen] == ' ') {
newline2[prtlen++] = c;
if (prtlen > prtlen2) prtlen2 = prtlen;
}
else {
j = prtlen;
prtwrite(&minus3, 0L);
prtwrite(&minus2, 0L);
nextcc = '+';
prtlen = j;
newline1[prtlen++] = c;
if (prtlen > prtlen1) prtlen1 = prtlen;
}
}
break;
}
}
return(0);
}
prtline(s)
unsigned char *s;
{
static int lineoffset, tt1len, pgnum;
GrafPtr gp;
char newpage;
int initskip, slen, leftoff, pglen;
static char tt1[MAXLINEWIDTH+1];
static char tt2[MAXLINEWIDTH+1];
int i;
char pbuff[12];
slen = strlen(s);
if (slen < 1) return; /* should never happen */
GetPort(&gp);
SetPort(prtport);
newpage = 0;
if (prtcc) {
leftoff = prtinfo.leftcc;
pglen = prtinfo.pagelencc;
}
else {
leftoff = prtinfo.left;
pglen = prtinfo.pagelength;
}
if (prpgopen == 0) { /* initial call for a new file */
lineoffset = pglen;
newpage = 1;
initskip = 1;
pgnum = 0;
maketitles(tt1, tt2, &tt1len);
}
switch(s[0]) { /* interpret carriage control */
case '0':
lineoffset += 2;
initskip = lineoffset - pglen;
if (initskip > 0) newpage = 1;
break;
case '-':
lineoffset += 3;
initskip = lineoffset - pglen;
if (initskip > 0) newpage = 1;
break;
case '+':
break;
case '1':
initskip = 1;
newpage = 1;
break;
default:
lineoffset ++;
initskip = lineoffset - pglen;
if (initskip > 0) newpage = 1;
break;
}
if (newpage) {
if (prpgopen) PrClosePage(prtport);
PrOpenPage(prtport, 0L);
prpgopen = 1;
TextFont(prtinfo.fontnum);
TextSize(prtinfo.pointsize);
PicComment(155, 0, 0L); /* line layout off */
lineoffset = 0;
pgnum++;
if (!prtcc) {
setmem(tt1+tt1len, prtinfo.titlewidth-tt1len, 0x20);
if (pgnum > 999) sprintf(pbuff, "Page%4d", pgnum%10000);
else sprintf(pbuff, "Page %d", pgnum);
i = strlen(pbuff);
movmem(pbuff, tt1+prtinfo.titlewidth-i, i);
i = prtinfo.titlewidth - tt1len - i - strlen(tt2);
if (i >= 4) movmem(tt2, tt1+tt1len+(i/2), strlen(tt2));
MoveTo(leftoff, lineoffset*prtinfo.leading+prtinfo.top);
DrawText(tt1, 0, prtinfo.titlewidth);
lineoffset++;
if (i < 4) {
MoveTo(leftoff, lineoffset*prtinfo.leading+prtinfo.top);
DrawText(tt2, 0, strlen(tt2));
lineoffset++;
}
lineoffset += prtinfo.headmarg;
}
lineoffset += initskip-1;
}
if (slen > 1) {
MoveTo(leftoff, lineoffset*prtinfo.leading+prtinfo.top);
DrawText(s+1, 0, slen-1);
}
SetPort(gp);
}
maketitles(tt1, tt2, tt1len)
char *tt1, *tt2;
int * tt1len;
{
short tlen;
static char * days[7] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
static char * months[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec"};
static char am[3] = "AM";
static char pm[3] = "PM";
char * timeptr;
short hours;
long datesecs;
/* first line */
setmem(tt1, prtinfo.titlewidth, 0x20);
tt1[prtinfo.titlewidth] = 0;
movmem("File: \"", tt1, 7);
tlen = strlen(macFName+1);
if (tlen > prtinfo.titlewidth-16) tlen = prtinfo.titlewidth-16;
movmem(macFName+1, tt1+7, tlen);
if (tlen < prtinfo.titlewidth-16) {
tt1[tlen+7] = '"';
(*tt1len) = tlen+8;
}
else (*tt1len) = tlen+7;
/* second line */
Date2Secs(&wdate, &datesecs);
Secs2Date(datesecs, &wdate);
if (wdate.hour < 12) timeptr = am;
else timeptr = pm;
if (wdate.hour == 0) hours = 12;
else if (wdate.hour > 12) hours = wdate.hour - 12;
else hours = wdate.hour;
sprintf(tt2, "Last Modified: %s, %s %d, %d %d:%02d:%02d %s",
days[wdate.dayOfWeek-1], months[wdate.month-1], wdate.day, wdate.year,
hours, wdate.minute, wdate.second, timeptr);
}